<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<body>
</body>

</html>
<script>
//2021.05.01 于北京丰台修订 
//2021.05.11 补充函数参数

//函数的两个阶段： 定义阶段 调用阶段  
     //1.定义阶段 
        //声明式函数(具名函数)
        function fn(){}
        //赋值式函数
        var fn=function(){}
        
     //2.调用阶段：
        //两种定义函数的方式不一样，但是调用方式一样， 都是函数名()
        //声明式函数可以在定义之前调用，也可以在定义之后调用；
        fn()
        function fn(){
                console.log(1)
        }
        fn()
        //赋值式函数只能在定义之后调用
        fn()              //fn is not a function
        var fn = function(){//等号后面相当于简单的赋值；
                console.log(1)
        }

//函数的参数 es5 es6  
        //形参(上)：
                //即定义在函数内部的变量(局部变量) + 只能载函数内部使用外部不可以使用 + 形参的值由函数调用时传递的实参决定  
        //实参(下)：
                //函数调用的时候给形参进行赋值的 (传递值)

//函数的传参：
       //普通传参：
        function fn(a,b){
        console.log(a,b)
        }
        fn(10,20)
       //使用变量传参(项目常用 )
        var m=10;
        var n=10;
        function fn(a,b){
        console.log(a,b)
        }
        fn(m,n)

//参数的个数关系(即形参和实参)
       //1.两种参数一致 一一对应
       //2.实参多(下面的) + 获取行参的长度 arguments.length  + 前面的一一对应，多出来的实参在函数体内没有变量接收，不能直接使用
       //3.形参多(上面的) + 获取实参的长度 函数名.length     + 前面的一一对应， 多出来的形参没有实参赋值，那么就是undefined;

//return返回 作用?  
        function fn(){
              return 10*10    //return右边的代码会被返回；注：返回不等于输出
              console.log(10) //return 后面的代码不会执行；
        }
        fn()                    
        console.log(fn())
        return false          //针对on....出来的东西 阻止默认事件

        //1.终止函数写在return后面的代码全部就不执行了 
        //2.给函数一个返回值；写在return右边的代码 + 即让函数执行完毕后由有个结果
            //*不写ruturn 函数的返回值就是undefined 
            //*写了ruturn 没写返回内容返回值还是undefined
            //*如果写了return 后面有东西，那么写什么，该函数的返回值就是什么；
            //*如果写了return 但是后面没有东西，那么该函数的返回值是undefined
            //*多个ruturn 只执行第一层的 后面代码不会执行

        //看demo 
        //用return返回值：输出查看：
        function f4(a,b){ 
                return a+b
        }
        var rel=f4(10,30)      //在此处赋值有个变量rel 
        console.log(rel)       //40  赋值给一个变量，输出这个变量查看；
        console.log(f4(10,30)) //或者输出的时候直接调用查看；
                        

        //函数的调用问题：
        //当函数调用时，才会执行函数中的代码；
        fn(实参)           //自调用函数
        setInterval(fn,100)//调用函数这个动作交由定时器来完成         不需括号；
        box.onclick=fn     //调用函数这个动作交由box的点击事件来完成  不需括号；

                        

        //函数中的变量：在函数中定义的变量，会成为局部变量;定义在函数外部的变量会成为全局变量；
                //局部变量只能在该函数内部访问(只能在这个函数内使用；在函数外不能使用这个变量)；
                //注：在函数中没有用var声明的变量会成为全局变量；

			
	
函数中的this指向：
        注：函数中的this指向，与函数的定义没有关系，只看函数的调用；
                1.全局调用：this->window
                        函数名() 
                2.对象调用：this->点前面是谁就是谁
                        对象.函数()
                        var obj={
                           name:'小明',
                           fn:function(){
                                   console.log(this)//obj
                           }
                        }
                        obj.fn()
                3.定时器处理函数：this->window   
                        setTimeout/clearInterval(function(){},20);
                4.事件处理函数 this->事件源(谁身上的事件) 
                        box.事件=function(){}
                5.自执行函数： this->window
                        (function(a){
                           console.log(this)
                        })(10)
                6.箭头函数没有this，他的this指向上下文，也就是外部作用域的this
                        var a=()=>{
                                console.log(this) 
                        }
                7.构造函数的  this->当前实例 
                        function Person(name,age){ 
                                console.log(this) 
                                this.name=name 
                        }
                        var p1=new Person('小红',10) 

        修改this指向：
        call()
                语法：函数名.call()
                1参 是你要改变的函数的his指向：不写或写null都为window；
                第二个参数开始：依次是给函数传递参数
                        var obj={'name':'小明'}
                        fn.call(obj)表示fn函数在执行的时候，内部的this指向obj
                        注：元素.onclick=fn.call()这儿不能设置call；
        apply()
                语法：函数名.call()
                1参 是你要改变的函数的this指向；
                第二个参数是一个数组：数组里面每一项依次是给函数传递参数
                        fn.call(obj,[10,20,30])
        bind()  says(say){
                setInterval(function(){
                        console.log(this.tyep + "say" + say)
                }.bind(this) ,1000)
        }

        
                        
        //默认参数值 
        //检测某个参数是否==undefined 没有传这个参数 就给他赋值一个 
        function makeKing(name){
                neme = (typeof name!=="undefined")?name:"cdd";
                return `king ${name} aa`
        }
        console.log(makeKing())           //king  cdd aa
        console.log(makeKing("Louis"))    //king  Louis aa
        //var area = (width=1, height=1) => width*height  ES6 


        //对象参数 比较常见在vue jq中 即函数的参数为对象的 
        var opt = {
            width: 10,
            height: 10
        }
        function area() {
            this.width = opt.width || 1;
            this.height = opt.height || 1;
            return this.width * this.height
        }
        console.log(area(opt));   //100 

        //省略参数，参数默认值  ||短路 
        function sub(a, b) {
            a = a || 0;
            b = b || 0;
            return a - b;
        }
        console.log(sub(5,1)); //4 


        // 函数的返回值 为对象的时候   
        function Robot(name) {
            this.name = name
        }
        Robot.prototype.init = function() {
        return {
                say: function () {
                console.log('My name is ' + this.name)
                }.bind(this),
                dance:  function(danceName) {
                console.log('My dance name is ' + danceName)
                }
        };
        }
        var robotA = new Robot('A');
        robotA.init().say(); // "My name is A"
        var robotB = new Robot('B');
        robotB.init().say(); // "My name is B"







        </script>

